#pragma once

#include <nlohmann/json.hpp>
#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <chrono>

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

namespace SimpleRest {

using namespace nlohmann;

// HTTP方法枚举
enum class HttpMethod {
    GET,
    POST,
    PUT,
    DELETE
};

// HTTP请求结构体（简化版）
struct HttpRequest {
    HttpMethod method;
    std::string uri;
    json body;
};

// HTTP响应结构体（简化版）
struct HttpResponse {
    int status_code;
    json body;
};

// RESTful API处理器类
class RestApiHandler {
public:
    using HandlerFunction = std::function<HttpResponse(const HttpRequest&)>;

    // 添加路由处理器
    void addRoute(const std::string& uri, HttpMethod method, HandlerFunction handler) {
        std::string key = methodToString(method) + " " + uri;
        route_handlers[key] = handler;
    }

    // 持久化存储数据到文件
    void saveDataToFile(const std::string& filename, const json& data) {
        std::ofstream file(filename);
        file << data.dump(4);
        file.close();
    }

    // 从文件加载数据
    json loadDataFromFile(const std::string& filename) {
        json data;
        std::ifstream file(filename);
        if (file.is_open()) {
            file >> data;
            file.close();
        }
        return data;
    }

    // 启动服务器
    void startServer(int port) {
        int server_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (server_fd == 0) {
            perror("socket failed");
            exit(EXIT_FAILURE);
        }

        struct sockaddr_in address;
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        address.sin_port = htons(port);

        if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
            perror("bind failed");
            exit(EXIT_FAILURE);
        }

        if (listen(server_fd, 3) < 0) {
            perror("listen");
            exit(EXIT_FAILURE);
        }

        std::cout << "Server listening on port " << port << std::endl;

        while (true) {
            struct sockaddr_in client_addr;
            socklen_t addrlen = sizeof(client_addr);
            int client_socket = accept(server_fd, (struct sockaddr*)&client_addr, &addrlen);
            if (client_socket < 0) {
                perror("accept");
                continue;
            }

            std::thread([this, client_socket]() {
                handleClient(client_socket);
            }).detach();
        }
    }

private:
    std::map<std::string, HandlerFunction> route_handlers;
    mutable std::mutex mtx;

    std::string methodToString(HttpMethod method) {
        switch (method) {
            case HttpMethod::GET: return "GET";
            case HttpMethod::POST: return "POST";
            case HttpMethod::PUT: return "PUT";
            case HttpMethod::DELETE: return "DELETE";
            default: return "UNKNOWN";
        }
    }

    HttpResponse createResponse(int status_code, const json& body) {
        HttpResponse response;
        response.status_code = status_code;
        response.body = body;
        return response;
    }

    void handleClient(int client_socket) {
        std::lock_guard<std::mutex> lock(mtx);

        char buffer[1024] = {0};
        read(client_socket, buffer, 1024);

        // 解析HTTP请求
        std::string request(buffer);
        size_t method_end = request.find(' ');
        size_t uri_end = request.find(' ', method_end + 1);
        size_t body_start = request.find("\r\n\r\n") + 4;

        std::string method_str = request.substr(0, method_end);
        HttpMethod method = stringToMethod(method_str);
        std::string uri = request.substr(method_end + 1, uri_end - method_end - 1);
        std::string body = request.substr(body_start);

        // 处理请求
        HttpRequest simple_req;
        simple_req.method = method;
        simple_req.uri = uri;
        try {
            simple_req.body = json::parse(body);
        } catch (...) {
            sendResponse(client_socket, createResponse(400, "Invalid JSON"));
            close(client_socket);
            return;
        }

        HttpResponse response = handleRequest(simple_req);
        sendResponse(client_socket, response);

        close(client_socket);
    }

    void sendResponse(int client_socket, const HttpResponse& response) {
        std::string resp_str = "HTTP/1.1 " + std::to_string(response.status_code) + " OK\r\n";
        resp_str += "Content-Type: application/json\r\n";
        resp_str += "Content-Length: " + std::to_string(response.body.dump().size()) + "\r\n";
        resp_str += "\r\n";
        resp_str += response.body.dump();

        send(client_socket, resp_str.c_str(), resp_str.size(), 0);
    }

    HttpMethod stringToMethod(const std::string& method_str) {
        if (method_str == "GET") return HttpMethod::GET;
        if (method_str == "POST") return HttpMethod::POST;
        if (method_str == "PUT") return HttpMethod::PUT;
        if (method_str == "DELETE") return HttpMethod::DELETE;
        return HttpMethod::GET; // 默认返回GET
    }
};

} // namespace SimpleRest